package com.doctracker.service;

import com.doctracker.model.Person;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 文件改名服务类
 * 支持根据动态规则批量重命名文件
 */
public class FileRenameService {
    
    /**
     * 改名规则元素
     */
    public static class RuleElement {
        private String type; // "field" 或 "text"
        private String value; // 字段名或文本内容
        
        public RuleElement(String type, String value) {
            this.type = type;
            this.value = value;
        }
        
        // Getter和Setter
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getValue() { return value; }
        public void setValue(String value) { this.value = value; }
    }
    
    /**
     * 改名结果
     */
    public static class RenameResult {
        private String originalName;
        private String newName;
        private boolean success;
        private String errorMessage;
        
        public RenameResult(String originalName, String newName, boolean success, String errorMessage) {
            this.originalName = originalName;
            this.newName = newName;
            this.success = success;
            this.errorMessage = errorMessage;
        }
        
        // Getter方法
        public String getOriginalName() { return originalName; }
        public String getNewName() { return newName; }
        public boolean isSuccess() { return success; }
        public String getErrorMessage() { return errorMessage; }
    }
    
    /**
     * 从人员列表中获取所有可用的字段
     * 
     * @param people 人员列表
     * @return 所有可用字段的集合
     */
    public Set<String> getAvailableFields(List<Person> people) {
        Set<String> allFields = new HashSet<>();
        
        // 基础字段
        allFields.add("姓名");
        
        // 动态字段
        for (Person person : people) {
            allFields.addAll(person.getAvailableFields());
        }
        
        System.out.println("检测到可用字段: " + allFields);
        return allFields;
    }
    
    /**
     * 根据规则生成新文件名
     * 
     * @param person 人员信息
     * @param ruleElements 规则元素列表
     * @param originalFileName 原文件名
     * @return 新文件名
     */
    public String generateNewFileName(Person person, List<RuleElement> ruleElements, String originalFileName) {
        StringBuilder newNameBuilder = new StringBuilder();
        
        for (RuleElement element : ruleElements) {
            if ("field".equals(element.getType())) {
                // 字段类型
                String fieldValue = getFieldValue(person, element.getValue());
                if (fieldValue != null && !fieldValue.isEmpty()) {
                    newNameBuilder.append(fieldValue);
                } else {
                    newNameBuilder.append("[" + element.getValue() + "]"); // 显示字段名作为占位符
                }
            } else if ("text".equals(element.getType())) {
                // 文本类型
                newNameBuilder.append(element.getValue());
            }
        }
        
        // 保留原文件扩展名
        String extension = getFileExtension(originalFileName);
        String newFileName = newNameBuilder.toString();
        
        if (!extension.isEmpty()) {
            newFileName += "." + extension;
        }
        
        return newFileName;
    }
    
    /**
     * 获取字段值
     * 
     * @param person 人员信息
     * @param fieldName 字段名
     * @return 字段值
     */
    private String getFieldValue(Person person, String fieldName) {
        if ("姓名".equals(fieldName)) {
            return person.getName();
        } else {
            return person.getDynamicField(fieldName);
        }
    }
    
    /**
     * 获取文件扩展名
     * 
     * @param fileName 文件名
     * @return 扩展名（不包含点）
     */
    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
            return fileName.substring(lastDotIndex + 1);
        }
        return "";
    }
    
    /**
     * 预览改名效果
     * 
     * @param people 已匹配文件的人员列表
     * @param ruleElements 规则元素列表
     * @return 预览结果列表
     */
    public List<RenameResult> previewRename(List<Person> people, List<RuleElement> ruleElements) {
        List<RenameResult> previewResults = new ArrayList<>();
        
        for (Person person : people) {
            if (person.isHasSubmitted() && person.getFileName() != null) {
                String originalName = person.getFileName();
                String newName = generateNewFileName(person, ruleElements, originalName);
                
                // 检查新文件名是否有效
                boolean isValid = isValidFileName(newName);
                String errorMessage = isValid ? null : "文件名包含无效字符";
                
                previewResults.add(new RenameResult(originalName, newName, isValid, errorMessage));
            }
        }
        
        return previewResults;
    }
    
    /**
     * 执行批量改名
     * 
     * @param people 已匹配文件的人员列表
     * @param ruleElements 规则元素列表
     * @return 改名结果列表
     */
    public List<RenameResult> executeRename(List<Person> people, List<RuleElement> ruleElements) {
        List<RenameResult> results = new ArrayList<>();
        
        for (Person person : people) {
            if (person.isHasSubmitted() && person.getFilePath() != null) {
                String originalName = person.getFileName();
                String newName = generateNewFileName(person, ruleElements, originalName);
                
                try {
                    File originalFile = new File(person.getFilePath());
                    if (!originalFile.exists()) {
                        results.add(new RenameResult(originalName, newName, false, "原文件不存在"));
                        continue;
                    }
                    
                    // 构建新文件路径
                    File parentDir = originalFile.getParentFile();
                    File newFile = new File(parentDir, newName);
                    
                    // 检查新文件名是否已存在
                    if (newFile.exists()) {
                        results.add(new RenameResult(originalName, newName, false, "目标文件名已存在"));
                        continue;
                    }
                    
                    // 执行重命名
                    Path originalPath = originalFile.toPath();
                    Path newPath = newFile.toPath();
                    Files.move(originalPath, newPath, StandardCopyOption.REPLACE_EXISTING);
                    
                    // 更新Person对象中的文件信息
                    person.setFileName(newName);
                    person.setFilePath(newFile.getAbsolutePath());
                    
                    results.add(new RenameResult(originalName, newName, true, null));
                    System.out.println("文件改名成功: " + originalName + " → " + newName);
                    
                } catch (Exception e) {
                    results.add(new RenameResult(originalName, newName, false, "改名失败: " + e.getMessage()));
                    System.err.println("文件改名失败: " + originalName + " → " + newName + ", 错误: " + e.getMessage());
                }
            }
        }
        
        return results;
    }
    
    /**
     * 检查文件名是否有效
     * 
     * @param fileName 文件名
     * @return 是否有效
     */
    private boolean isValidFileName(String fileName) {
        if (fileName == null || fileName.trim().isEmpty()) {
            return false;
        }
        
        // Windows不允许的字符
        String invalidChars = "\\/:*?\"<>|";
        for (char c : invalidChars.toCharArray()) {
            if (fileName.indexOf(c) >= 0) {
                return false;
            }
        }
        
        // 不能以点结尾
        if (fileName.endsWith(".")) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 解析模板字符串为规则元素列表
     * 例如: "{班级}{姓名}第一次作业" → [field:班级, field:姓名, text:第一次作业]
     * 
     * @param template 模板字符串
     * @return 规则元素列表
     */
    public List<RuleElement> parseTemplate(String template) {
        List<RuleElement> elements = new ArrayList<>();
        
        Pattern fieldPattern = Pattern.compile("\\{([^}]+)\\}");
        Matcher matcher = fieldPattern.matcher(template);
        
        int lastEnd = 0;
        while (matcher.find()) {
            // 添加字段前的文本
            if (matcher.start() > lastEnd) {
                String text = template.substring(lastEnd, matcher.start());
                if (!text.isEmpty()) {
                    elements.add(new RuleElement("text", text));
                }
            }
            
            // 添加字段
            String fieldName = matcher.group(1);
            elements.add(new RuleElement("field", fieldName));
            
            lastEnd = matcher.end();
        }
        
        // 添加最后的文本
        if (lastEnd < template.length()) {
            String text = template.substring(lastEnd);
            if (!text.isEmpty()) {
                elements.add(new RuleElement("text", text));
            }
        }
        
        return elements;
    }
} 